import {
	IAbility,
	IContext,
	IParam,
	verifyNodeLinkCond,
	deepCopy,
	typeOf,
	UILogicParamService,
	UILogicParamType,
} from '@/core';
/**
 * 禁用
 * 基于template/src/ui-service/{{appEntities}}/{{uiLogics}}-ui-logic-base.ts.hbs生成
 * @export
 * @class DisableUILogicBase
 */
export class DisableUILogicBase {
	/**
	 * 返回结果
	 *
	 * @private
	 * @type {*}
	 * @memberof DisableUILogicBase
	 */
	private result: any;

	/**
	 * 行为附加参数
	 *
	 * @type {*}
	 * @memberof DisableUILogicBase
	 */
	public additionalParam: IParam = {};

	/**
	 * 界面逻辑上下文
	 *
	 * @private
	 * @type {IContext}
	 * @memberof DisableUILogicBase
	 */
	private appContext!: IContext;

	/**
	 * 界面逻辑视图参数
	 *
	 * @private
	 * @type {IParam}
	 * @memberof DisableUILogicBase
	 */
	private viewParam!: IParam;

	/**
	 * 默认逻辑处理参数名称
	 *
	 * @private
	 * @type {string}
	 * @memberof DisableUILogicBase
	 */
	private defaultParamName: string = '';

	/**
	 * 应用上下文参数名称
	 *
	 * @private
	 * @type {string}
	 * @memberof DisableUILogicBase
	 */
	private navContextParamName: string = '';

	/**
	 * 视图参数名称
	 *
	 * @private
	 * @type {string}
	 * @memberof DisableUILogicBase
	 */
	private navViewParamParamName: string = '';

	/**
	 * 当前容器参数名称
	 *
	 * @private
	 * @type {string}
	 * @memberof DisableUILogicBase
	 */
	private activeContainerParamName: string = '';

	/**
	 * 当前激活部件参数名称
	 *
	 * @private
	 * @type {string}
	 * @memberof DisableUILogicBase
	 */
	private activeCtrlParamName: string = '';

	/**
	 * 当前激活视图对象名称
	 *
	 * @private
	 * @type {string}
	 * @memberof DisableUILogicBase
	 */
	private activeViewParamName: string = '';

	/**
	 * 上一次调用返回参数名称
	 *
	 * @private
	 * @type {string}
	 * @memberof DisableUILogicBase
	 */
	private lastReturnParamName: string = '';

	/**
	 * 逻辑参数Map
	 *
	 * @private
	 * @type {Map<string, IParam>}
	 * @memberof DisableUILogicBase
	 */
	private logicParamMap: Map<string, IParam> = new Map();

	/**
	 * 绑定上一次调用返回参数
	 *
	 * @memberof DisableUILogicBase
	 */
	public bindLastReturnParam(value: any) {
		const lastReturnParam = this.logicParamMap.get(this.lastReturnParamName);
		if (lastReturnParam) {
			lastReturnParam.bind(value);
		}
	}

	/**
	 * 默认逻辑处理参数
	 *
	 * @memberof DisableUILogicBase
	 */
	get defaultParam(): any {
		return this.logicParamMap.get(this.defaultParamName);
	}

	/**
	 * 上下文数据（包括应用上下文和逻辑局部上下文参数）
	 *
	 * @readonly
	 * @memberof DisableUILogicBase
	 */
	get context() {
		const navContextParam = this.logicParamMap.get(this.navContextParamName);
		if (navContextParam) {
			return navContextParam.getReal();
		} else {
			return this.appContext;
		}
	}

	/**
	 * 视图参数数据（包括外部传入视图参数和逻辑局部视图参数）
	 *
	 * @readonly
	 * @memberof DisableUILogicBase
	 */
	get viewParams() {
		const navViewParamParam = this.logicParamMap.get(
			this.navViewParamParamName
		);
		if (navViewParamParam) {
			return navViewParamParam.getReal();
		} else {
			return this.viewParam;
		}
	}

	/**
	 * 获取逻辑处理参数
	 *
	 * @param {string} key 逻辑处理参数的codeName
	 * @memberof UIActionContext
	 */
	private getParam(key: string): any {
		return this.logicParamMap.get(key);
	}

	/**
	 * Creates an instance of DisableUILogicBase
	 *
	 * @param {IParam} [opts={}]
	 * @memberof DisableUILogicBase
	 */
	constructor(opts: IParam = {}) {}

	/**
	 * 逻辑参数模型
	 *
	 * @private
	 * @type {any[]}
	 * @memberof DisableUILogicBase
	 */
	private logicParamModels: any[] = [
		{
			name: '传入变量',
			codeName: 'Default',
			default: true,
			entityParam: true,
		},
		{
			name: '当前布局',
			codeName: 'curCtrl',
			activeCtrlParam: true,
			ctrlParam: true,
		},
		{
			name: 'Temp',
			codeName: 'Temp',
			simpleParam: true,
		},
	];

	/**
	 * 初始化逻辑参数
	 * @param context 应用上下文
	 * @param viewParams 视图参数
	 * @param data 业务数据
	 * @param event 事件对象
	 * @param ability 当前环境能力
	 * @memberof DisableUILogicBase
	 */
	private initLogicParams<T extends IAbility>(
		context: IContext,
		viewParams: IParam,
		data: IParam,
		$event: MouseEvent,
		ability: T
	) {
		this.appContext = deepCopy(context);
		this.viewParam = deepCopy(viewParams);
		this.additionalParam = {
			data,
			$event,
			ctrl: ability.viewCtx.ctrl,
			actionContext: ability,
		};
		this.logicParamModels.forEach((model: IParam) => {
			if (model.default) {
				this.defaultParamName = model.codeName;
			}
			if (model.navContextParam) {
				this.navContextParamName = model.codeName;
			}
			if (model.navViewParamParam) {
				this.navViewParamParamName = model.codeName;
			}
			if (model.activeContainerParam) {
				this.activeContainerParamName = model.codeName;
			}
			if (model.activeCtrlParam) {
				this.activeCtrlParamName = model.codeName;
			}
			if (model.activeViewParam) {
				this.activeViewParamName = model.codeName;
			}
			if (model.lastReturnParam) {
				this.lastReturnParamName = model.codeName;
			}
			const uiLogicParamInstance = UILogicParamService.getLogicParamInstance(
				this,
				model,
				{
					data,
					context,
					viewParams,
					$event,
					ctrl: ability.viewCtx.ctrl,
					actionContext: ability,
				}
			);
			this.logicParamMap.set(model.codeName, uiLogicParamInstance);
		});
	}

	/**
	 * 执行界面逻辑之前
	 * @param context 应用上下文
	 * @param viewParams 视图参数
	 * @param data 业务数据
	 * @param event 事件对象
	 * @param ability 当前环境能力
	 * @memberof DisableUILogicBase
	 */
	private beforeExecute<T extends IAbility>(
		context: IContext,
		viewParams: IParam,
		data: IParam,
		event: MouseEvent,
		ability: T
	) {
		this.initLogicParams(context, viewParams, data, event, ability);
	}

	/**
	 * 执行界面逻辑
	 * @param context 应用上下文
	 * @param viewParams 视图参数
	 * @param data 业务数据
	 * @param event 事件对象
	 * @param ability 当前环境能力
	 * @memberof DisableUILogicBase
	 */
	public async execute<T extends IAbility>(
		context: IContext,
		viewParams: IParam,
		data: IParam,
		event: MouseEvent,
		ability: T
	) {
		try {
			this.beforeExecute(context, viewParams, data, event, ability);
			await this.execute_Begin_node();
			return this.result;
		} catch (error: any) {
			throw new Error(
				`${error && error.message ? error.message : '发生未知错误！'}`
			);
		}
	}

	/**
	 * 执行 开始 节点
	 *
	 * @protected
	 * @memberof DisableUILogicBase
	 */
	protected async execute_Begin_node() {
		this.result = this.defaultParam.getReal();
		console.log(`已完成执行 开始节点，操作参数数据如下:`);
		if (this.logicParamMap && this.logicParamMap.size > 0) {
			for (let [key, value] of this.logicParamMap) {
				console.log(key, deepCopy(value.getReal()));
			}
		}
		console.log(`即将执行消息弹窗节点`);
		await this.execute_MSGBOX1_node();
	}

	/**
	 * 执行 结束 节点
	 *
	 * @protected
	 * @memberof DisableUILogicBase
	 */
	protected async execute_END1_node() {}

	/**
	 * 执行 实体行为 节点
	 *
	 * @protected
	 * @memberof DisableUILogicBase
	 */
	protected async execute_DEACTION1_node() {
		try {
			const dstParam = this.getParam('Default');
			if (dstParam) {
				const service = await App.getDataService(
					'Sys_deploy_system',
					this.context
				);
				if (
					service &&
					service['Update'] &&
					service['Update'] instanceof Function
				) {
					const getTempContext = (data: IParam) => {
						const tempContext = deepCopy(this.context);
						if (data) {
							Object.assign(tempContext, data);
						}
						return tempContext;
					};
					const tempContext = getTempContext(dstParam.getReal());
					const res = await service['Update'](
						tempContext,
						dstParam.getReal() ? dstParam.getReal() : {}
					);
					if (res.success && res.data) {
						this.bindLastReturnParam(res.data);
					} else {
						throw new Error(`执行实体行为失败`);
					}
				}
			} else {
				throw new Error(`操作参数缺失！`);
			}
			console.log(`已完成执行 实体行为节点，操作参数数据如下:`);
			if (this.logicParamMap && this.logicParamMap.size > 0) {
				for (let [key, value] of this.logicParamMap) {
					console.log(key, deepCopy(value.getReal()));
				}
			}
			console.log(`即将执行视图部件调用节点`);
			await this.execute_VIEWCTRLINVOKE1_node();
		} catch (error: any) {
			throw new Error(
				`执行 实体行为 节点 ${
					error && error.message ? error.message : '发生未知错误！'
				}`
			);
		}
	}

	/**
	 * 执行 实体行为 节点
	 *
	 * @protected
	 * @memberof DisableUILogicBase
	 */
	protected async execute_DEACTION2_node() {
		try {
			const dstParam = this.getParam('Default');
			if (dstParam) {
				const service = await App.getDataService(
					'Sys_deploy_system',
					this.context
				);
				if (service && service['Get'] && service['Get'] instanceof Function) {
					const getTempContext = (data: IParam) => {
						const tempContext = deepCopy(this.context);
						if (data) {
							Object.assign(tempContext, data);
						}
						return tempContext;
					};
					const tempContext = getTempContext(dstParam.getReal());
					const res = await service['Get'](
						tempContext,
						dstParam.getReal() ? dstParam.getReal() : {}
					);
					if (res.success && res.data) {
						const retParam = this.getParam('Default');
						if (retParam) {
							retParam.bind(res.data);
						}
						this.bindLastReturnParam(res.data);
					} else {
						throw new Error(`执行实体行为失败`);
					}
				}
			} else {
				throw new Error(`操作参数缺失！`);
			}
			console.log(`已完成执行 实体行为节点，操作参数数据如下:`);
			if (this.logicParamMap && this.logicParamMap.size > 0) {
				for (let [key, value] of this.logicParamMap) {
					console.log(key, deepCopy(value.getReal()));
				}
			}
			console.log(`即将执行准备参数节点`);
			await this.execute_PREPAREJSPARAM1_node();
		} catch (error: any) {
			throw new Error(
				`执行 实体行为 节点 ${
					error && error.message ? error.message : '发生未知错误！'
				}`
			);
		}
	}

	/**
	 * 执行 准备参数 节点
	 *
	 * @protected
	 * @memberof DisableUILogicBase
	 */
	protected async execute_PREPAREJSPARAM1_node() {
		try {
			//  目标数据
			const dstParam_0: any = this.getParam('Default');
			let result_0: any = null;
			result_0 = '0';
			dstParam_0.set('enabled', result_0);
			console.log(`已完成执行 准备参数节点，操作参数数据如下:`);
			if (this.logicParamMap && this.logicParamMap.size > 0) {
				for (let [key, value] of this.logicParamMap) {
					console.log(key, deepCopy(value.getReal()));
				}
			}
			console.log(`即将执行实体行为节点`);
			await this.execute_DEACTION1_node();
		} catch (error: any) {
			throw new Error(
				`执行 准备参数 节点 ${
					error && error.message ? error.message : '发生未知错误!'
				}`
			);
		}
	}

	/**
	 * 执行 消息弹窗 节点
	 *
	 * @protected
	 * @memberof DisableUILogicBase
	 */
	protected async execute_MSGBOX1_node() {
		return new Promise<void>((resolve: any) => {
			const options = {};
			Object.assign(options, { okText: '是', cancelText: '否' });
			const msgBoxParam: any = this.getParam('Temp');
			const data: any = msgBoxParam ? msgBoxParam.getReal() : {};
			Object.assign(options, { type: 'info' });
			const msgBox = App.getDialogHelper();
			const handleMsgBox = async (result: boolean) => {
				const resultText = result ? 'yes' : 'no';
				msgBoxParam.bind(resultText);
				this.bindLastReturnParam(resultText);
				console.log(`已完成执行 消息弹窗节点，操作参数数据如下:`);
				if (this.logicParamMap && this.logicParamMap.size > 0) {
					for (let [key, value] of this.logicParamMap) {
						console.log(key, deepCopy(value.getReal()));
					}
				}
				const linkCond_0 = {
					name: '',
					logicType: 'GROUP',
					notMode: false,
					groupOP: 'AND',
					childLogics: [
						{
							name: 'Temp 等于(=) yes',
							logicType: 'SINGLE',
							condOP: 'EQ',
							verifyValue: this.getParam('Temp').getReal(),
							value: 'yes',
						},
					],
				};
				if (verifyNodeLinkCond(linkCond_0)) {
					console.log(`即将执行实体行为节点`);
					await this.execute_DEACTION2_node();
				}
				const linkCond_1 = {
					name: '',
					logicType: 'GROUP',
					notMode: false,
					groupOP: 'AND',
					childLogics: [
						{
							name: 'Temp 等于(=) no',
							logicType: 'SINGLE',
							condOP: 'EQ',
							verifyValue: this.getParam('Temp').getReal(),
							value: 'no',
						},
					],
				};
				if (verifyNodeLinkCond(linkCond_1)) {
					console.log(`即将执行结束节点`);
					await this.execute_END1_node();
				}
				resolve();
			};
			Object.assign(options, {
				title: data && data.title ? data.title : '询问',
				content: data && data.message ? data.message : `确认要停用选中的系统？`,
				ok: () => {
					handleMsgBox(true);
				},
				cancel: () => {
					handleMsgBox(false);
				},
			});
			msgBox.custom(options);
		});
	}

	/**
	 * 执行 视图部件调用 节点
	 *
	 * @protected
	 * @memberof DisableUILogicBase
	 */
	protected async execute_VIEWCTRLINVOKE1_node() {
		try {
			const invokeUICtrl = this.getParam('curCtrl').getReal();
			if (
				invokeUICtrl['refresh'] &&
				invokeUICtrl['refresh'] instanceof Function
			) {
				const result = await invokeUICtrl['refresh']();
				const invokeParam = this.getParam('Default');
				if (invokeParam) {
					invokeParam.bind(result);
				}
				this.bindLastReturnParam(result);
			} else {
				throw new Error(`curCtrl界面对象不存在refresh方法`);
			}
			console.log(`已完成执行 视图部件调用节点，操作参数数据如下:`);
			if (this.logicParamMap && this.logicParamMap.size > 0) {
				for (let [key, value] of this.logicParamMap) {
					console.log(key, deepCopy(value.getReal()));
				}
			}
			console.log(`即将执行结束节点`);
			await this.execute_END1_node();
		} catch (error: any) {
			throw new Error(
				`执行视图部件调用节点 视图部件调用错误：${
					error && error.message
						? error.message
						: '界面对象调用 refresh 方法发生异常'
				}`
			);
		}
	}
}
